package com.ruoyi.common.utils;

import com.ruoyi.common.annotation.Excel;
import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordTemplateUtils {
    
    /**
     * 通用Word模板填充方法
     * @param entity 数据实体对象
     * @param templatePath 模板路径
     * @param outputStream 输出流
     */
    public static void fillTemplate(Object entity, String templatePath, OutputStream outputStream) throws Exception {
        // 1. 通过反射获取字段映射
        Map<String, String> dataMap = getFieldMapping(entity);

        // 2. 加载模板文档
        XWPFDocument doc = new XWPFDocument(new FileInputStream(templatePath));

        // 3. 执行替换操作
        replacePlaceholders(doc, dataMap);

        // 4. 保存生成文档
        doc.write(outputStream);
    }

    /**
     * 通过反射获取字段映射关系
     */
    private static Map<String, String> getFieldMapping(Object entity) throws IllegalAccessException {
        Map<String, String> dataMap = new HashMap<>();
        Class<?> clazz = entity.getClass();
        
        // 遍历所有字段（包括父类字段）
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            
            // 获取Excel注解配置
            Excel excelAnnotation = field.getAnnotation(Excel.class);
            if (excelAnnotation != null) {
                String fieldName = excelAnnotation.name();
                Object value = field.get(entity);
                
                // 处理不同字段类型
                if (value != null) {
                    dataMap.put(fieldName, value.toString());
                }
            }
        }
        return dataMap;
    }

    /**
     * 执行占位符替换
     */
    private static void replacePlaceholders(XWPFDocument doc, Map<String, String> dataMap) {
        // 替换段落内容
        for (XWPFParagraph p : doc.getParagraphs()) {
            replaceInRuns(p.getRuns(), dataMap);
        }

        // 替换表格内容
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph p : cell.getParagraphs()) {
                        replaceInRuns(p.getRuns(), dataMap);
                    }
                }
            }
        }
    }

    /**
     * 在Run对象中执行替换
     */
    private static void replaceInRuns(List<XWPFRun> runs, Map<String, String> dataMap) {
        for (XWPFRun run : runs) {
            String text = run.getText(0);
            if (text != null) {
                // 匹配格式如："行政区划：" 或 "${行政区划}"
                for (Map.Entry<String, String> entry : dataMap.entrySet()) {
                    String placeholder1 = "${" + entry.getKey() + "}"; // 变量格式
                    
                    if (text.contains(placeholder1)) {
                        run.setText(text.replace(placeholder1, entry.getValue()), 0);
                    }
                }
            }
        }
    }
}
